home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Mail / pine3.92 / pico / region.c < prev    next >
C/C++ Source or Header  |  1996-03-14  |  8KB  |  349 lines

  1. #if    !defined(lint) && !defined(DOS)
  2. static char rcsid[] = "$Id: region.c,v 4.18 1996/03/15 07:41:11 hubert Exp $";
  3. #endif
  4. /*
  5.  * Program:    Region management routines
  6.  *
  7.  *
  8.  * Michael Seibel
  9.  * Networks and Distributed Computing
  10.  * Computing and Communications
  11.  * University of Washington
  12.  * Administration Builiding, AG-44
  13.  * Seattle, Washington, 98195, USA
  14.  * Internet: mikes@cac.washington.edu
  15.  *
  16.  * Please address all bugs and comments to "pine-bugs@cac.washington.edu"
  17.  *
  18.  *
  19.  * Pine and Pico are registered trademarks of the University of Washington.
  20.  * No commercial use of these trademarks may be made without prior written
  21.  * permission of the University of Washington.
  22.  * 
  23.  * Pine, Pico, and Pilot software and its included text are Copyright
  24.  * 1989-1996 by the University of Washington.
  25.  * 
  26.  * The full text of our legal notices is contained in the file called
  27.  * CPYRIGHT, included with this distribution.
  28.  *
  29.  */
  30. /*
  31.  * The routines in this file
  32.  * deal with the region, that magic space
  33.  * between "." and mark. Some functions are
  34.  * commands. Some functions are just for
  35.  * internal use.
  36.  */
  37. #include        <stdio.h>
  38. #include    "osdep.h"
  39. #include    "pico.h"
  40. #include    "estruct.h"
  41. #include        "edef.h"
  42.  
  43. /*
  44.  * Kill the region. Ask "getregion"
  45.  * to figure out the bounds of the region.
  46.  * Move "." to the start, and kill the characters.
  47.  * Bound to "C-W".
  48.  */
  49. killregion(f, n)
  50. {
  51.     REGION          region;
  52.     static long     times = 1L;
  53.     static long     backoff = 4L;
  54.  
  55.     if (curbp->b_mode&MDVIEW)        /* don't allow this command if    */
  56.       return(rdonly());            /* we are in read only mode    */
  57.  
  58.     if (getregion(®ion) != TRUE){
  59.     if((lastflag&CFKILL) == 0){
  60.         emlwrite("Line Deleted.%s", !(times % backoff) ? 
  61.              " (Could also use ctrl-^ to mark text for cutting)" : "");
  62.  
  63.         if(!(times++ % backoff))     /* if message shown, reset backoff */
  64.           backoff = backoff << 1;
  65.     }
  66.     
  67.     return (killtext(f, n));
  68.     }else {
  69.     mlerase();
  70.     }
  71.  
  72.     if ((lastflag&CFKILL) == 0)        /* This is a kill type  */
  73.       kdelete();            /* command, so do magic */
  74.  
  75.     thisflag |= CFKILL;            /* kill buffer stuff.   */
  76.     curwp->w_dotp = region.r_linep;
  77.     curwp->w_doto = region.r_offset;
  78.     curwp->w_markp = NULL;
  79. #ifdef    _WINDOWS
  80.     mswin_allowcopycut(NULL);
  81. #endif
  82.  
  83.     if(ldelete(region.r_size, TRUE)){
  84.     if(curwp->w_dotp == curwp->w_linep && curwp->w_dotp == curbp->b_linep){
  85.         curwp->w_force = 0;        /* Center dot. */
  86.         curwp->w_flag |= WFFORCE;
  87.     }
  88.  
  89.     return(TRUE);
  90.     }
  91.  
  92.     return (FALSE);
  93. }
  94.  
  95.  
  96. /*
  97.  * Copy all of the characters in the
  98.  * region to the kill buffer. Don't move dot
  99.  * at all. This is a bit like a kill region followed
  100.  * by a yank. Bound to "M-W".
  101.  */
  102. copyregion(f, n)
  103. {
  104.     register LINE   *linep;
  105.     register int    loffs;
  106.     register int    s;
  107.     REGION          region;
  108.  
  109.     if ((s=getregion(®ion)) != TRUE)
  110.       return (s);
  111.  
  112.     if ((lastflag&CFKILL) == 0)        /* Kill type command.   */
  113.       kdelete();
  114.  
  115.     thisflag |= CFKILL;
  116.     linep = region.r_linep;        /* Current line.        */
  117.     loffs = region.r_offset;        /* Current offset.      */
  118.     while (region.r_size--) {
  119.     if (loffs == llength(linep)) {  /* End of line.         */
  120.         if ((s=kinsert('\n')) != TRUE)
  121.           return (s);
  122.         linep = lforw(linep);
  123.         loffs = 0;
  124.     } else {                        /* Middle of line.      */
  125.         if ((s=kinsert(lgetc(linep, loffs).c)) != TRUE)
  126.           return (s);
  127.         ++loffs;
  128.     }
  129.     }
  130.  
  131.     return (TRUE);
  132. }
  133.  
  134.  
  135. /*
  136.  * Lower case region. Zap all of the upper
  137.  * case characters in the region to lower case. Use
  138.  * the region code to set the limits. Scan the buffer,
  139.  * doing the changes. Call "lchange" to ensure that
  140.  * redisplay is done in all buffers. Bound to
  141.  * "C-X C-L".
  142.  */
  143. lowerregion(f, n)
  144. {
  145.     register LINE   *linep;
  146.     register int    loffs;
  147.     register int    c;
  148.     register int    s;
  149.     REGION          region;
  150.     CELL            ac;
  151.  
  152.     ac.a = 0;
  153.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  154.       return(rdonly());    /* we are in read only mode    */
  155.  
  156.     if ((s=getregion(®ion)) != TRUE)
  157.       return (s);
  158.  
  159.     lchange(WFHARD);
  160.     linep = region.r_linep;
  161.     loffs = region.r_offset;
  162.     while (region.r_size--) {
  163.     if (loffs == llength(linep)) {
  164.         linep = lforw(linep);
  165.         loffs = 0;
  166.     } else {
  167.         c = lgetc(linep, loffs).c;
  168.         if (c>='A' && c<='Z'){
  169.         ac.c = c+'a'-'A';
  170.         lputc(linep, loffs, ac);
  171.         }
  172.         ++loffs;
  173.     }
  174.     }
  175.  
  176.     return (TRUE);
  177. }
  178.  
  179. /*
  180.  * Upper case region. Zap all of the lower
  181.  * case characters in the region to upper case. Use
  182.  * the region code to set the limits. Scan the buffer,
  183.  * doing the changes. Call "lchange" to ensure that
  184.  * redisplay is done in all buffers. Bound to
  185.  * "C-X C-L".
  186.  */
  187. upperregion(f, n)
  188. {
  189.     register LINE   *linep;
  190.     register int    loffs;
  191.     register int    c;
  192.     register int    s;
  193.     REGION          region;
  194.     CELL            ac;
  195.  
  196.     ac.a = 0;
  197.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  198.       return(rdonly());    /* we are in read only mode    */
  199.  
  200.     if ((s=getregion(®ion)) != TRUE)
  201.       return (s);
  202.  
  203.     lchange(WFHARD);
  204.     linep = region.r_linep;
  205.     loffs = region.r_offset;
  206.     while (region.r_size--) {
  207.     if (loffs == llength(linep)) {
  208.         linep = lforw(linep);
  209.         loffs = 0;
  210.     } else {
  211.         c = lgetc(linep, loffs).c;
  212.         if (c>='a' && c<='z'){
  213.         ac.c = c - 'a' + 'A';
  214.         lputc(linep, loffs, ac);
  215.         }
  216.         ++loffs;
  217.     }
  218.     }
  219.  
  220.     return (TRUE);
  221. }
  222.  
  223. /*
  224.  * This routine figures out the
  225.  * bounds of the region in the current window, and
  226.  * fills in the fields of the "REGION" structure pointed
  227.  * to by "rp". Because the dot and mark are usually very
  228.  * close together, we scan outward from dot looking for
  229.  * mark. This should save time. Return a standard code.
  230.  * Callers of this routine should be prepared to get
  231.  * an "ABORT" status; we might make this have the
  232.  * conform thing later.
  233.  */
  234. getregion(rp)
  235. register REGION *rp;
  236. {
  237.     register LINE   *flp;
  238.     register LINE   *blp;
  239.     long        fsize;
  240.     register long   bsize;
  241.  
  242.     if (curwp->w_markp == NULL) {
  243.     return (FALSE);
  244.     }
  245.  
  246.     if (curwp->w_dotp == curwp->w_markp) {
  247.     rp->r_linep = curwp->w_dotp;
  248.     if (curwp->w_doto < curwp->w_marko) {
  249.         rp->r_offset = curwp->w_doto;
  250.         rp->r_size = curwp->w_marko-curwp->w_doto;
  251.     } else {
  252.         rp->r_offset = curwp->w_marko;
  253.         rp->r_size = curwp->w_doto-curwp->w_marko;
  254.     }
  255.     return (TRUE);
  256.     }
  257.  
  258.     blp = curwp->w_dotp;
  259.     bsize = curwp->w_doto;
  260.     flp = curwp->w_dotp;
  261.     fsize = llength(flp)-curwp->w_doto+1;
  262.     while (flp!=curbp->b_linep || lback(blp)!=curbp->b_linep) {
  263.     if (flp != curbp->b_linep) {
  264.         flp = lforw(flp);
  265.         if (flp == curwp->w_markp) {
  266.         rp->r_linep = curwp->w_dotp;
  267.         rp->r_offset = curwp->w_doto;
  268.         rp->r_size = fsize + curwp->w_marko;
  269.         return (TRUE);
  270.         }
  271.  
  272.         fsize += llength(flp) + 1;
  273.     }
  274.  
  275.     if (lback(blp) != curbp->b_linep) {
  276.         blp = lback(blp);
  277.         bsize += llength(blp)+1;
  278.         if (blp == curwp->w_markp) {
  279.         rp->r_linep = blp;
  280.         rp->r_offset = curwp->w_marko;
  281.         rp->r_size = bsize - curwp->w_marko;
  282.         return (TRUE);
  283.         }
  284.     }
  285.     }
  286.  
  287.     emlwrite("Bug: lost mark", NULL);
  288.     return (FALSE);
  289. }
  290.  
  291.  
  292. /*
  293.  * set the highlight attribute accordingly on all characters in region
  294.  */
  295. markregion(attr)
  296.     int attr;
  297. {
  298.     register LINE   *linep;
  299.     register int    loffs;
  300.     register int    s;
  301.     REGION          region;
  302.     CELL            ac;
  303.  
  304.     if ((s=getregion(®ion)) != TRUE)
  305.       return (s);
  306.  
  307.     lchange(WFHARD);
  308.     linep = region.r_linep;
  309.     loffs = region.r_offset;
  310.     while (region.r_size--) {
  311.     if (loffs == llength(linep)) {
  312.         linep = lforw(linep);
  313.         loffs = 0;
  314.     } else {
  315.         ac = lgetc(linep, loffs);
  316.         ac.a = attr;
  317.         lputc(linep, loffs, ac);
  318.         ++loffs;
  319.     }
  320.     }
  321.  
  322.     return (TRUE);
  323. }
  324.  
  325.  
  326. /*
  327.  * clear all the attributes of all the characters in the buffer?
  328.  * this is real dumb.  Movement with mark set needs to be smarter!
  329.  */
  330. unmarkbuffer()
  331. {
  332.     register LINE   *linep;
  333.     register int     n;
  334.     CELL c;
  335.  
  336.     linep = curwp->w_linep;
  337.     while(lforw(linep) != curwp->w_linep){
  338.     n = llength(linep);
  339.     for(n=0; n < llength(linep); n++){
  340.         c = lgetc(linep, n);
  341.         c.a = 0;
  342.         lputc(linep, n, c);
  343.     }
  344.  
  345.     linep = lforw(linep);
  346.     }
  347.     
  348. }
  349.